#!/usr/bin/env python

"""
A replicator plugin waits for new snapshot version notifications.
"""

import cvmfs_plugin
from replica_common import *
import time
import pickle
import threading

class Replicator(cvmfs_plugin.Plugin):

    def __init__(self, target):
        cvmfs_plugin.Plugin.__init__(self, target)
        self.subscribe("REPLICA.NEWVERSION")

        self.invoke_lock = threading.Lock()

    def handle_msg(self, src, subject, body):
        if subject == 'REPLICA.NEWVERSION':
            rep_cmd = pickle.loads(body)
            self.do_replicate(rep_cmd)

    def do_replicate(self, cmd):
        self.view_lock.acquire()
        reply = ReplicationReply()
        reply.seq = cmd.seq
        reply.vid = self.view.vid
        if not self.stable:
            reply.ok = False
        else:
            for v in cmd.versions:
                print 'replication command %s@[%d, %d] (me: [%d, %d]' % \
                        (v.version, v.viewstamp[0], v.viewstamp[1], \
                         self.viewstamp[0], self.viewstamp[1])
                if v.viewstamp < self.viewstamp:
                    # old replication command
                    continue
                elif v.viewstamp == self.viewstamp:
                    # the right replication command
                    print "replicating version %s (viewstamp: [%d, %d])..." % \
                            (v.version, v.viewstamp[0], v.viewstamp[1])
                    time.sleep(5)
                    self.viewstamp[1] += 1 # increment the seqno of my viewstamp

            # tell the primary that i have done the replication
            reply.ok = True
        self.unicast(self.view.primary, 'REPLICA.CLIENT_REPLY',
                pickle.dumps(reply))
        self.view_lock.release()

    def view_change(self):
        print 'vid on replicator has been changed to %d' % self.view.vid
        self.viewstamp = [self.view.vid, 0]

if __name__ == "__main__":
    import sys
    replicator = Replicator(int(sys.argv[1]))
    
    while True:
        time.sleep(1)

